package edu.nf.vrs.reservation.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Lv
 * @date 2022/3/29
 */
@Configuration
public class RabbitConfig {

    public static final String EXCHANGE_NAME = "reserve.exchange";
    public static final String QUEUE_NAME = "reserve.queue";
    public static final String ROUTER_KEY = "reserve.*";
    /**
     * 声明死信交换机名称
     */
    public static final String DEAD_EXCHANGE_NAME = "reserve.dead.exchange";
    /**
     * 声明死信队列名称
     */
    public static final String DEAD_QUEUE_NAME = "reserve.dead.queue";
    /**
     * 死信队列路由key
     */
    public static final String DEAD_ROUTER_KEY = "reserve.dead.key";

    /**
     * 装配Topic类型的Exchange
     */
    @Bean
    public TopicExchange exchange(){
        return new TopicExchange(EXCHANGE_NAME, true, false);
    }

    /**
     * 装配死信Exchange
     * @return
     */
    @Bean
    public DirectExchange deadExchange() {
        return new DirectExchange(DEAD_EXCHANGE_NAME);
    }

    /**
     * 配置普通业务的消息队列并关联死信交换机，当这个队列中的消息被拒绝或达到重试次数后，
     * 通过死信路由的key将其发送到对应的死信交换机
     * @return
     */
    @Bean
    public Queue queue() {
        return QueueBuilder.durable(QUEUE_NAME)
                //设置死信交换机的名称
                .withArgument("x-dead-letter-exchange", DEAD_EXCHANGE_NAME)
                //设置死信队列路由的key
                .withArgument("x-dead-letter-routing-key", DEAD_ROUTER_KEY)
                .build();
    }

    /**
     * 配置死信队列
     */
    @Bean
    public Queue deadQueue() {
        return new Queue(DEAD_QUEUE_NAME, true);
    }

    /**
     * 将queue绑定到exchange
     */
    @Bean
    public Binding binding(){
        return BindingBuilder.bind(queue()).to(exchange()).with(ROUTER_KEY);
    }

    /**
     * 将死信队列绑定到死信交换机上
     *
     * @return
     */
    @Bean
    public Binding deadLetterBinding() {
        return BindingBuilder.bind(deadQueue()).to(deadExchange()).with(DEAD_ROUTER_KEY);
    }
}
